/*
 * @lc app=leetcode.cn id=239 lang=javascript
 *
 * [239] 滑动窗口最大值
 *
 * https://leetcode.cn/problems/sliding-window-maximum/description/
 *
 * algorithms
 * Hard (49.64%)
 * Likes:    3144
 * Dislikes: 0
 * Total Accepted:    870.8K
 * Total Submissions: 1.8M
 * Testcase Example:  '[1,3,-1,-3,5,3,6,7]\n3'
 *
 * 给你一个整数数组 nums，有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
 * 个数字。滑动窗口每次只向右移动一位。
 * 
 * 返回 滑动窗口中的最大值 。
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：nums = [1,3,-1,-3,5,3,6,7], k = 3
 * 输出：[3,3,5,5,6,7]
 * 解释：
 * 滑动窗口的位置                最大值
 * ---------------               -----
 * [1  3  -1] -3  5  3  6  7       3
 * ⁠1 [3  -1  -3] 5  3  6  7       3
 * ⁠1  3 [-1  -3  5] 3  6  7       5
 * ⁠1  3  -1 [-3  5  3] 6  7       5
 * ⁠1  3  -1  -3 [5  3  6] 7       6
 * ⁠1  3  -1  -3  5 [3  6  7]      7
 * 
 * 
 * 示例 2：
 * 
 * 
 * 输入：nums = [1], k = 1
 * 输出：[1]
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * 1 <= nums.length <= 10^5
 * -10^4 <= nums[i] <= 10^4
 * 1 <= k <= nums.length
 * 
 * 
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 * 窗口范围[i,j],从最左侧窗口[1-k,j]到最右侧[j-k,j] 循环遍历数组。声明一个队列，对头永远存放窗口最大值，队尾的值如果小于nums[j]，则一直出队列，否则入队列。当队列头部最大值在窗口之外（queue[0]===nums[i-1]）则头部出队列。
 */
 var maxSlidingWindow = function(nums, k) {
    let res = [], queue = [];
    for(let j = 0, i = 1 - k; j < nums.length; i++, j++) {
        if(queue[0] === nums[i-1] && i>0) {
            queue.shift();
        }
        while(queue.length > 0 && queue[queue.length-1] < nums[j]) {
            queue.pop();
        }
        queue.push(nums[j]);
        if(i>=0) {
            res.push(queue[0]);
        }
    }
    return res;
};
// @lc code=end

